package com.companyName.sample.data.config;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * Created by guojun on 2016/3/27.
 */
//@EnableAspectJAutoProxy
@Configuration
@AutoConfigureAfter(MybatisConfig.class)
@EnableTransactionManagement
public class AspectConfig  implements TransactionManagementConfigurer {

    @Autowired
    DataSource dataSource;

    @Bean
    @Override
    @ConditionalOnMissingBean
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    @ConditionalOnMissingBean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }
/*	@Bean
	public TransactionInterceptor transactionInterceptor(){
		Properties attributes = new Properties();
		attributes.setProperty("*", "PROPAGATION_REQUIRED");
		TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
		transactionInterceptor.setTransactionManager(annotationDrivenTransactionManager());
		transactionInterceptor.setTransactionAttributes(attributes);
		return transactionInterceptor;
	}*/

	/*<tx:method name="save*" propagation="REQUIRED" />
	<tx:method name="delete*" propagation="REQUIRED" />
	<tx:method name="update*" propagation="REQUIRED" />
	<tx:method name="transfer*" propagation="REQUIRED" />
	<tx:method name="insert*" propagation="REQUIRED" />
	<tx:method name="change*" propagation="REQUIRED" />
	<tx:method name="do*" propagation="REQUIRED" />PROPAGATION_REQUIRED
	<tx:method name="*" propagation="REQUIRED" read-only="true" />*/

    @Bean
    @ConditionalOnMissingBean
    public TransactionInterceptor transactionInterceptor() {
        Properties attributes = new Properties();
        attributes.setProperty("get*", "PROPAGATION_REQUIRED");
        attributes.setProperty("put*", "PROPAGATION_REQUIRED");
        attributes.setProperty("post*", "PROPAGATION_REQUIRED");
        attributes.setProperty("delete*", "PROPAGATION_REQUIRED");
        TransactionInterceptor txAdvice = new TransactionInterceptor(annotationDrivenTransactionManager(), attributes);
        return txAdvice;
    }

    /*@Bean
    public TransactionInterceptor txAdvice(DataSource dataSource) {
        DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        Properties attributes = new Properties();
        attributes.setProperty("*", "PROPAGATION_REQUIRED");
        TransactionInterceptor txAdvice = new TransactionInterceptor(annotationDrivenTransactionManager, attributes);
        return txAdvice;
    }
    @Bean
    public Advisor transactionAdvisor() {
        AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor = new AspectJExpressionPointcutAdvisor();
        aspectJExpressionPointcutAdvisor.setExpression("execution(* com.companyName.sample.*.*.*.*(..))");
        aspectJExpressionPointcutAdvisor.setAdvice(transactionInterceptor());
        return aspectJExpressionPointcutAdvisor;
    }*/

	@Bean
    @ConditionalOnMissingBean
	public AspectJExpressionPointcut aspectJExpressionPointcut(){
		AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
		pointcut.setExpression("execution(* com.companyName.sample.service.impl.*.*(..))");
		return pointcut;
	}

	@Bean
    @ConditionalOnMissingBean
	public DefaultPointcutAdvisor defaultPointcutAdvisor(){
		DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
		advisor.setPointcut(aspectJExpressionPointcut());
		advisor.setAdvice(transactionInterceptor());
		return advisor;
	}

}
